<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .banner{width: 300px;height:90px;margin: 0 auto;position: relative;}

    .banner .imgbox{position: absolute;left:0px;}
    .banner .imgbox img{width: 300px;height: 90px;float: left;}

    .banner .btns input{position: absolute;width: 30px;height:30px;top: 30px;}
    .banner .btns .left{left:0;}
    .banner .btns .right{right:0;}
  </style>
</head>
<body>
  <div class="banner box1">
    <div class="imgbox">
    </div>
    <div class="btns">
      <input type="button" value="<" class="left">
      <input type="button" value=">" class="right">
    </div>
  </div>

  <div class="banner box2">
    <div class="imgbox">
    </div>
    <div class="btns">
      <input type="button" value="<" class="left">
      <input type="button" value=">" class="right">
    </div>
  </div>
</body>
<script>

  // 模拟后台给的图片数据
  const bannerData = [{
    name:"图1",
    src:"../imgs/banner1.jpg"
  },{
    name:"图2",
    src:"../imgs/banner2.jpg"
  },{
    name:"图3",
    src:"../imgs/banner3.jpg"
  },{
    name:"图4",
    src:"../imgs/banner4.jpg"
  },{
    name:"图5",
    src:"../imgs/banner5.jpg"
  }];

  // 分析：点击按钮滑动图片
  // 数据：按钮，图片，初始索引
  // 方法：绑定事件，计算图片索引，根据图片索引滑动图片，计时器持续修改位置直到到达目标

  // 设计：
  // function banner(){
  //   按钮，图片，初始索引
  //   this.left = 左按钮
  //   this.right = 左按钮
  //   this.imgbox = 图片容器
  //   this.imgs = 图片
  //   this.index = 索引
  // }
  // 初始化页面布局
  // banner.prototype.init = function(){}
  // 绑定事件功能
  // banner.prototype.addEvent = function(){}
  // 计算索引功能
  // banner.prototype.computedIndex = function(){}
  // 切换图片功能
  // banner.prototype.changeImg = function(){}
  // 运动功能
  // banner.prototype.move = function(){}

  // 编程
  function banner( { left, right, imgbox, index=0, data } ){
    this.left = left;
    this.right = right;
    this.imgbox = imgbox;
    this.index = index;
    this.data = data;

    this.init();
    this.addEvent();
  }
  // 初始化页面布局
  banner.prototype.init = function(){
    let str = "";
    this.data.forEach(val=>{
      str += `<img src="${val.src}" alt="${val.name}">`;
    })
    this.imgbox.innerHTML = str;
    this.width = this.imgbox.children[0].offsetWidth;
    this.imgbox.style.width = this.data.length * this.width + "px";
    this.imgbox.style.left = -this.index * this.width + "px";
  }
  // 绑定事件功能
  banner.prototype.addEvent = function(){
    const that = this;
    this.left.onclick = function(){
      that.computedIndex(1);
    }
    this.right.onclick = function(){
      that.computedIndex(2);
    }
  }
  // 计算索引功能
  banner.prototype.computedIndex = function(d){
    if(d === 1){
      if(this.index === 0){
        this.index = this.data.length-1;
      }else{
        this.index--;
      }
    }else{
      if(this.index === this.data.length-1){
        this.index = 0;
      }else{
        this.index++;
      }
    }
    this.changeImg();
  }
  // 切换图片功能
  banner.prototype.changeImg = function(){
    this.move(this.imgbox, {
      left: -this.index * this.width
    })
  }
  // 运动功能
  banner.prototype.move = function(ele, obj, cb){
    clearInterval(ele.t)
    ele.t = setInterval(()=>{
      let state = true;
      for(let key in obj){
        let now = parseInt(getStyle(ele, key));
        let speed = (obj[key] - now) / 10;
        speed = speed < 0 ? Math.floor(speed) : Math.ceil(speed);
        ele.style[key] = now + speed + "px";
        if(now !== obj[key]) state = false;
      }
      if(state){
        clearInterval(ele.t);
        cb && cb();
      }
    }, 30);

    function getStyle(ele, attr){
      if(ele.currentStyle){
        return ele.currentStyle[attr];
      }else{
        return getComputedStyle(ele)[attr];
      }
    }
  }


  new banner({
    left:document.querySelector(".box1 .left"),
    right:document.querySelector(".box1 .right"),
    imgbox:document.querySelector(".box1 .imgbox"),
    index: 1,
    data: bannerData
  });


  new banner({
    left:document.querySelector(".box2 .left"),
    right:document.querySelector(".box2 .right"),
    imgbox:document.querySelector(".box2 .imgbox"),
    index: 3,
    data: bannerData
  });

  // 面向对象编程的特点：封装，继承，多态
  // 封装之后：忽略细节，重复使用，选择使用
  
  
</script>
</html>